#include "MyApplicationManager.h"

#include <windows.h>
#include <GL/gl.h>

#define _USE_MATH_DEFINES
#include <cmath>
#define TO_RADIANS_FACTOR (M_PI / 180.0)
#define TO_DEGREES_FACTOR (180.0 / M_PI)

#include <LDFToolkit/VisComponentGL.h>
#include <LDFToolkit/Utils/TextureManager.h>
#include <LDFToolkit/Strategies/Drawers/GradientBorderStrategy.h>
#include <LDFToolkit/Strategies/Drawers/ResizerHandleStrategy.h>
#include <LDFToolkit/Strategies/Containers/FrictionSurfaceStrategy.h>
#include <LDFToolkit/Strategies/Containers/CurrentBeltContainerStrategy.h>
#include <LDFToolkit/Strategies/Containers/BoundedContainerStrategy.h>
#include <LDFToolkit/Strategies/Observers/CurrentObserverStrategy.h>
#include <LDFToolkit/Strategies/Behaviors/LazyTossableRNTStrategy.h>
#include <LDFToolkit/Strategies/Behaviors/TranslationStrategy.h>
#include <LDFToolkit/Strategies/GUI/DestroyerStrategy.h>


#include <iostream>
#include <string>

#include "RSSCardStrategy.h"
#include "imageDrawingStrategy.h"
#include <QTimer>


MyApplicationManager::MyApplicationManager(FrameTimer* timer) : DefaultManager(timer)
{	
	initialize();
}

MyApplicationManager::~MyApplicationManager(void)
{
}


void MyApplicationManager::initComponents()
{
	float borderColor[4] = { 0.3, 0.5, 1.0, 1.0 };
	float selectedColor[4] = { 0.8, 0.6, 0.1, 1.0 };

	rootComponent = new VisComponentGL();
	rootComponent->setPosition(Point3f(400, 300, 0));
	rootComponent->setWidth(800);
	rootComponent->setHeight(600);
	GradientBorderStrategy* rootBorder = new GradientBorderStrategy();
	rootBorder->setBorderWidth(-10.0);
	rootBorder->setColor(borderColor);
	rootComponent->pushStrategy(rootBorder);
	FrictionSurfaceStrategy* friction = new FrictionSurfaceStrategy();
	friction->setBorderWidth(50);
	friction->setBorderHeight(50);
	rootComponent->pushStrategy(friction);
	rootComponent->getStrategy()->initPropertiesComponent();


	
	VisComponentGL* beltComponent1 = new VisComponentGL();
	beltComponent1->setPosition(600, 400);
	beltComponent1->setWidth(840);
	beltComponent1->setHeight(520);
	CurrentBeltContainerStrategy* currentBelt = new CurrentBeltContainerStrategy(100);
	currentBelt->setNumControlPoints(8);
	currentBelt->setSplineLevels(4);
	beltComponent1->pushStrategy(currentBelt);
	TranslationStrategy* currentBeltTranslation = new TranslationStrategy();
	beltComponent1->pushStrategy(currentBeltTranslation);
	addComponent(beltComponent1); 
	
	

	std::string textureFiles[10];
	for (int i = 0; i < 10; i++) {
		textureFiles[i] = "images/00";
		if( (i+1) < 10) textureFiles[i] += "0";
		textureFiles[i] += toString(i+1);
		textureFiles[i] += ".png";
		std::cout<< textureFiles[i] << std::endl;
	}

	for (int i = 0; i < 30; i++) {

		VisComponentGL* c = new VisComponentGL();
		c->setPosition(Point3f(obtainRandomFloat(800, 50), obtainRandomFloat(600, 50), 0));
		float dimension = obtainRandomFloat(150, 50);
		c->setWidth(dimension);
		c->setHeight(dimension);
		c->setRotationAngle(obtainRandomFloat(90) * TO_RADIANS_FACTOR);
		imageDrawingStrategy* imageStrategy = new imageDrawingStrategy(textureFiles[i%10]);
		c->pushStrategy(imageStrategy);
		ResizerHandleStrategy* resizerHandle = new ResizerHandleStrategy();
		resizerHandle->setColor(borderColor);
		resizerHandle->setSelectedColor(selectedColor);
		c->pushStrategy(resizerHandle);

		BorderStrategy* border = new BorderStrategy();
		border->setColor(borderColor);
		border->setSelectedColor(selectedColor);
		c->pushStrategy(border);
		LazyTossableRNTStrategy* rnt = new LazyTossableRNTStrategy();
		rnt->setColor(selectedColor);
		rnt->setFrictionCoefficient(1.0);
		rnt->setStaticFrictionCoefficient(10.0);
		c->pushStrategy(rnt);
		CurrentObserverStrategy* currentObserver = new CurrentObserverStrategy();
		c->pushStrategy(currentObserver);
		c->setLeaf(true);
		addComponent(c);
	}

	unsigned int theTex;
	glGenTextures(1, &theTex);

	for (int i=0; i<10 ; i++)
	{
		float quadBorderColor[4] = { 0.5, 0.5, 0.5, 1.0 };

		VisComponentGL* quad = new VisComponentGL();
		quad->setPosition(Point3f(obtainRandomFloat(800, 50), obtainRandomFloat(600, 50), 0));
		float dimensionW = obtainRandomFloat(300, 200);
		float dimensionH = obtainRandomFloat(150, 50);
		quad->setWidth(dimensionW);
		quad->setHeight(dimensionH);
		quad->setRotationAngle(obtainRandomFloat(90) * TO_RADIANS_FACTOR);
		std::string textToDisplay("Programming is good!!! Large Display Framework is amaizing");
		RSSCardStrategy* cardStrateg = new RSSCardStrategy(&theTex, "images/0002.png", textToDisplay);
		quad->pushStrategy(cardStrateg);
		ResizerHandleStrategy* resizerHandle = new ResizerHandleStrategy();
		resizerHandle->setColor(quadBorderColor);
		resizerHandle->setSelectedColor(selectedColor);
		quad->pushStrategy(resizerHandle);
		BorderStrategy* border = new BorderStrategy();
		border->setColor(quadBorderColor);
		border->setSelectedColor(selectedColor);
		quad->pushStrategy(border);
		LazyTossableRNTStrategy* rnt = new LazyTossableRNTStrategy();
		rnt->setColor(selectedColor);
		rnt->setFrictionCoefficient(1.0);
		rnt->setStaticFrictionCoefficient(10.0);
		quad->pushStrategy(rnt);
		CurrentObserverStrategy* currentObserver = new CurrentObserverStrategy();
		quad->pushStrategy(currentObserver);
		quad->setLeaf(true);
		addComponent(quad);

	}


}
